package com.hardydou.lang;

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

/**
 * @author ：hardy
 * @description： 同步队列案例<br />
 * 1、轻量级容器、无内部数据结构
 * 2、公平模式底层是TransferQueue
 * 3、非公平模式底层是 TransferStack
 * 4、执行take操作后阻塞消失，只能确保数据传输成功、并不能保证业务处理成功
 * @date ：Created in 2021/1/17
 * @Copyright ：Hardydou.com
 */
public class SyncQueueCase {
    SynchronousQueue<Item> queue = new SynchronousQueue<>();
    AtomicInteger n = new AtomicInteger(0);

    public SyncQueueCase() {
    }

    public SyncQueueCase(SynchronousQueue<Item> queue) {
        this.queue = queue;
    }

    class Item {
        int id;
        int value;

        public Item(int value) {
            this.id = value;
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public void setValue(int value) {
            this.value = value;
        }

        public int getId() {
            return id;
        }

        @Override
        public String toString() {
            return "Item{" +
                    "id=" + id +
                    ", value=" + value +
                    '}';
        }
    }

    public Producor newProducor() {
        return new Producor();
    }


    class Producor extends Thread {
        @Override
        public void run() {
            try {
                Item item = new Item(n.incrementAndGet());
                System.out.println("材料-开始传送 ：" + item);
                queue.put(item);
                System.out.println("材料-传输完成 ：" + item);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public Consumer newConsumer() {
        return new Consumer();
    }

    public Consumer newConsumer(java.util.function.Consumer consumer) {
        return new Consumer(consumer);
    }

    class Consumer extends Thread {
        java.util.function.Consumer<Item> consumer = new java.util.function.Consumer<Item>() {
            @Override
            public void accept(Item o) {
                o.setValue(o.getValue() + 2);
                System.out.println("材料-加工完成 ：" + o);
            }
        };

        public Consumer() {
        }


        public Consumer(java.util.function.Consumer consumer) {
            this.consumer = consumer;
        }

        @Override
        public void run() {
            try {
                Item item = queue.take();
                TimeUnit.SECONDS.sleep(1);
                consumer.accept(item);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

}
